package com.haixee.parkdemo.auth.service.impl;

import com.haixee.parkdemo.auth.dao.*;
import com.haixee.parkdemo.auth.entity.dto.RoleFieldDTO;
import com.haixee.parkdemo.auth.entity.dto.ViewFieldDTO;
import com.haixee.parkdemo.auth.entity.dto.ViewInfoDTO;
import com.haixee.parkdemo.auth.enums.AclType;
import com.haixee.parkdemo.auth.enums.Resp;
import com.haixee.parkdemo.auth.model.RoleField;
import com.haixee.parkdemo.auth.model.View;
import com.haixee.parkdemo.auth.model.ViewInfo;
import com.haixee.parkdemo.auth.service.ViewService;
import com.haixee.parkdemo.common.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class ViewServiceImpl implements ViewService {


    @Autowired
    private ViewCustomMapper viewCustomMapper;

    @Autowired
    private ViewInfoCustomMapper viewInfoCustomMapper;

    @Autowired
    private ViewFieldDTOMapper viewFieldDTOMapper;

    @Autowired
    private RoleFieldCustomMapper roleFieldCustomMapper;


    @Autowired
    private RoleFieldDTOMapper roleFieldDTOMapper;


    @Override
    public List<ViewInfoDTO> getAllView() {

        List<View> views = viewCustomMapper.selectAll();
        if (views.size() == 0) {
            return new ArrayList<>();
        }

        List<ViewInfoDTO> dtoList = new ArrayList<>();
        Map<Integer, ViewInfoDTO> map = new HashMap<>();
        for (View view : views) {
            ViewInfoDTO dto = new ViewInfoDTO();
            dto.setId(view.getId());
            dto.setName(view.getName());
            dtoList.add(dto);

            map.put(view.getId(), dto);
        }

        List<ViewInfo> viewInfoList = viewInfoCustomMapper.selectAll();
        for (ViewInfo viewInfo : viewInfoList) {
            ViewInfoDTO dto = map.get(viewInfo.getViewId());
            if (dto != null) {
                dto.getChildren().add(viewInfo);
            }
        }

        return dtoList;
    }

    @Override
    public void updateRoleView(Integer roleId, Integer fieldId, Byte type, Boolean use) {

        // 1. 查询字段对应业务数据
        ViewFieldDTO viewFieldDTO = viewFieldDTOMapper.selectById(fieldId);
        if (viewFieldDTO == null) {
            log.error("[更新角色字段权限数据],字段不存在,roleId:[{}], fieldId:[{}], type:[{}], use:[{}]", roleId, fieldId, type, use);
            throw new BusinessException(Resp.FIELD_NOT_EXIST);
        }

        // 2. 判断是否能修改
        if ((AclType.READ.getType() == type && !viewFieldDTO.getIsVisible() ) ||
                (AclType.WRITE.getType() == type && !viewFieldDTO.getIsEditable())
        ) {
            log.error("[更新角色字段权限数据],字段无法操作,roleId:[{}], fieldId:[{}], type:[{}], use:[{}]", roleId, fieldId, type, use);
            throw new BusinessException(Resp.FIELD_NOT_OPT);
        }

        // 3. 查询角色当前的字段配置
        List<RoleField> roleFields = roleFieldCustomMapper.selectByFieldId(fieldId);

        // 如果 不可编辑，需要保证不可见没有使用
        if (AclType.WRITE.getType() == type) {
            for (RoleField roleField : roleFields) {
                if (roleField.getAclType() == AclType.READ.getType()) {
                    log.error("[更新角色字段权限数据],不可见存在,不可编辑无法操作,roleId:[{}], fieldId:[{}], type:[{}], use:[{}]", roleId, fieldId, type, use);
                    throw new BusinessException(Resp.FIELD_NOT_OPT);
                }
            }
        }

        if (use) {
            List<RoleField> fields = new ArrayList<>();

            RoleField editField = new RoleField();
            editField.setFieldId(fieldId);
            editField.setRoleId(roleId);
            editField.setAclId(viewFieldDTO.getUpdateAcl());
            editField.setAclType(AclType.WRITE.getType());
            fields.add(editField);

            if (AclType.READ.getType() == type) {
                RoleField readField = new RoleField();
                readField.setFieldId(fieldId);
                readField.setRoleId(roleId);
                readField.setAclId(viewFieldDTO.getQueryAcl());
                readField.setAclType(AclType.READ.getType());
                fields.add(readField);
            }

            roleFieldCustomMapper.insertMany(fields);
        } else {
            // 删除
            roleFieldCustomMapper.deleteByRoleIdAndFieldIdAndAclType(roleId, fieldId, type);
        }
    }

    @Override
    public List<RoleFieldDTO> getRoleFields(Integer roleId) {
        return roleFieldDTOMapper.selectByRoleId(roleId);
    }
}
